/**
 * 语音识别工具类
 * 封装了 Web Speech API 的相关功能
 */

export class SpeechRecognitionManager {
  constructor(options = {}) {
    this.options = {
      continuous: true,
      interimResults: true,
      lang: 'zh-CN',
      maxAlternatives: 1,
      ...options
    };
    
    this.recognition = null;
    this.isSupported = false;
    this.isListening = false;
    this.callbacks = {};
    
    this.init();
  }
  
  /**
   * 初始化语音识别
   */
  init() {
    if ('webkitSpeechRecognition' in window) {
      this.recognition = new webkitSpeechRecognition();
      this.isSupported = true;
    } else if ('SpeechRecognition' in window) {
      this.recognition = new SpeechRecognition();
      this.isSupported = true;
    } else {
      console.warn('当前浏览器不支持语音识别功能');
      return;
    }
    
    this.setupRecognition();
  }
  
  /**
   * 配置语音识别参数
   */
  setupRecognition() {
    if (!this.recognition) return;
    
    Object.assign(this.recognition, this.options);
    
    // 绑定事件处理器
    this.recognition.onstart = () => {
      this.isListening = true;
      this.emit('start');
    };
    
    this.recognition.onend = () => {
      this.isListening = false;
      this.emit('end');
    };
    
    this.recognition.onresult = (event) => {
      this.handleResult(event);
    };
    
    this.recognition.onerror = (event) => {
      this.handleError(event);
    };
    
    this.recognition.onnomatch = () => {
      this.emit('nomatch');
    };
    
    this.recognition.onsoundstart = () => {
      this.emit('soundstart');
    };
    
    this.recognition.onsoundend = () => {
      this.emit('soundend');
    };
    
    this.recognition.onspeechstart = () => {
      this.emit('speechstart');
    };
    
    this.recognition.onspeechend = () => {
      this.emit('speechend');
    };
  }
  
  /**
   * 处理识别结果
   */
  handleResult(event) {
    let interimTranscript = '';
    let finalTranscript = '';
    
    for (let i = event.resultIndex; i < event.results.length; i++) {
      const result = event.results[i];
      const transcript = result[0].transcript;
      
      if (result.isFinal) {
        finalTranscript += transcript;
      } else {
        interimTranscript += transcript;
      }
    }
    
    this.emit('result', {
      finalTranscript,
      interimTranscript,
      results: event.results
    });
  }
  
  /**
   * 处理识别错误
   */
  handleError(event) {
    const errorMessages = {
      'no-speech': '未检测到语音输入',
      'audio-capture': '无法捕获音频，请检查麦克风',
      'not-allowed': '麦克风权限被拒绝',
      'network': '网络连接错误',
      'service-not-allowed': '语音识别服务不可用',
      'bad-grammar': '语法识别错误',
      'language-not-supported': '不支持的语言'
    };
    
    const message = errorMessages[event.error] || `未知错误: ${event.error}`;
    
    this.emit('error', {
      error: event.error,
      message
    });
  }
  
  /**
   * 开始语音识别
   */
  start() {
    if (!this.isSupported) {
      throw new Error('当前浏览器不支持语音识别功能');
    }
    
    if (this.isListening) {
      console.warn('语音识别已在运行中');
      return;
    }
    
    try {
      this.recognition.start();
    } catch (error) {
      console.error('启动语音识别失败:', error);
      throw error;
    }
  }
  
  /**
   * 停止语音识别
   */
  stop() {
    if (!this.recognition || !this.isListening) return;
    
    this.recognition.stop();
  }
  
  /**
   * 中止语音识别
   */
  abort() {
    if (!this.recognition) return;
    
    this.recognition.abort();
  }
  
  /**
   * 设置语言
   */
  setLanguage(lang) {
    if (this.recognition) {
      this.recognition.lang = lang;
      this.options.lang = lang;
    }
  }
  
  /**
   * 设置是否连续识别
   */
  setContinuous(continuous) {
    if (this.recognition) {
      this.recognition.continuous = continuous;
      this.options.continuous = continuous;
    }
  }
  
  /**
   * 设置是否返回中间结果
   */
  setInterimResults(interimResults) {
    if (this.recognition) {
      this.recognition.interimResults = interimResults;
      this.options.interimResults = interimResults;
    }
  }
  
  /**
   * 注册事件监听器
   */
  on(event, callback) {
    if (!this.callbacks[event]) {
      this.callbacks[event] = [];
    }
    this.callbacks[event].push(callback);
  }
  
  /**
   * 移除事件监听器
   */
  off(event, callback) {
    if (!this.callbacks[event]) return;
    
    if (callback) {
      const index = this.callbacks[event].indexOf(callback);
      if (index > -1) {
        this.callbacks[event].splice(index, 1);
      }
    } else {
      this.callbacks[event] = [];
    }
  }
  
  /**
   * 触发事件
   */
  emit(event, data) {
    if (!this.callbacks[event]) return;
    
    this.callbacks[event].forEach(callback => {
      try {
        callback(data);
      } catch (error) {
        console.error(`事件处理器执行错误 (${event}):`, error);
      }
    });
  }
  
  /**
   * 获取支持的语言列表
   */
  static getSupportedLanguages() {
    return [
      { code: 'zh-CN', name: '中文(普通话)', region: '中国大陆' },
      { code: 'zh-TW', name: '中文(繁体)', region: '台湾' },
      { code: 'zh-HK', name: '中文(粤语)', region: '香港' },
      { code: 'en-US', name: 'English', region: 'United States' },
      { code: 'en-GB', name: 'English', region: 'United Kingdom' },
      { code: 'ja-JP', name: '日本語', region: '日本' },
      { code: 'ko-KR', name: '한국어', region: '대한민국' },
      { code: 'fr-FR', name: 'Français', region: 'France' },
      { code: 'de-DE', name: 'Deutsch', region: 'Deutschland' },
      { code: 'es-ES', name: 'Español', region: 'España' },
      { code: 'es-MX', name: 'Español', region: 'México' },
      { code: 'it-IT', name: 'Italiano', region: 'Italia' },
      { code: 'pt-BR', name: 'Português', region: 'Brasil' },
      { code: 'ru-RU', name: 'Русский', region: 'Россия' },
      { code: 'ar-SA', name: 'العربية', region: 'السعودية' },
      { code: 'hi-IN', name: 'हिन्दी', region: 'भारत' },
      { code: 'th-TH', name: 'ไทย', region: 'ประเทศไทย' },
      { code: 'vi-VN', name: 'Tiếng Việt', region: 'Việt Nam' }
    ];
  }
  
  /**
   * 检查浏览器支持情况
   */
  static checkSupport() {
    return {
      speechRecognition: 'webkitSpeechRecognition' in window || 'SpeechRecognition' in window,
      mediaRecorder: 'MediaRecorder' in window,
      getUserMedia: 'mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices
    };
  }
  
  /**
   * 销毁实例
   */
  destroy() {
    if (this.recognition) {
      this.stop();
      this.recognition = null;
    }
    this.callbacks = {};
    this.isSupported = false;
    this.isListening = false;
  }
}

/**
 * 音频录制管理器
 */
export class AudioRecorderManager {
  constructor(options = {}) {
    this.options = {
      mimeType: 'audio/webm;codecs=opus',
      audioBitsPerSecond: 128000,
      ...options
    };
    
    this.mediaRecorder = null;
    this.audioChunks = [];
    this.stream = null;
    this.isRecording = false;
    this.callbacks = {};
  }
  
  /**
   * 开始录音
   */
  async startRecording() {
    try {
      this.stream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          sampleRate: 44100,
          channelCount: 1
        }
      });
      
      this.audioChunks = [];
      this.mediaRecorder = new MediaRecorder(this.stream, this.options);
      
      this.mediaRecorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
          this.audioChunks.push(event.data);
        }
      };
      
      this.mediaRecorder.onstop = () => {
        const audioBlob = new Blob(this.audioChunks, { 
          type: this.options.mimeType 
        });
        this.emit('recordingComplete', audioBlob);
        this.cleanup();
      };
      
      this.mediaRecorder.onerror = (event) => {
        this.emit('error', event.error);
      };
      
      this.mediaRecorder.start(1000); // 每秒收集数据
      this.isRecording = true;
      this.emit('recordingStart');
      
    } catch (error) {
      console.error('开始录音失败:', error);
      this.emit('error', error);
      throw error;
    }
  }
  
  /**
   * 停止录音
   */
  stopRecording() {
    if (this.mediaRecorder && this.isRecording) {
      this.mediaRecorder.stop();
      this.isRecording = false;
      this.emit('recordingStop');
    }
  }
  
  /**
   * 暂停录音
   */
  pauseRecording() {
    if (this.mediaRecorder && this.isRecording) {
      this.mediaRecorder.pause();
      this.emit('recordingPause');
    }
  }
  
  /**
   * 恢复录音
   */
  resumeRecording() {
    if (this.mediaRecorder) {
      this.mediaRecorder.resume();
      this.emit('recordingResume');
    }
  }
  
  /**
   * 清理资源
   */
  cleanup() {
    if (this.stream) {
      this.stream.getTracks().forEach(track => track.stop());
      this.stream = null;
    }
    this.mediaRecorder = null;
    this.isRecording = false;
  }
  
  /**
   * 注册事件监听器
   */
  on(event, callback) {
    if (!this.callbacks[event]) {
      this.callbacks[event] = [];
    }
    this.callbacks[event].push(callback);
  }
  
  /**
   * 移除事件监听器
   */
  off(event, callback) {
    if (!this.callbacks[event]) return;
    
    if (callback) {
      const index = this.callbacks[event].indexOf(callback);
      if (index > -1) {
        this.callbacks[event].splice(index, 1);
      }
    } else {
      this.callbacks[event] = [];
    }
  }
  
  /**
   * 触发事件
   */
  emit(event, data) {
    if (!this.callbacks[event]) return;
    
    this.callbacks[event].forEach(callback => {
      try {
        callback(data);
      } catch (error) {
        console.error(`事件处理器执行错误 (${event}):`, error);
      }
    });
  }
  
  /**
   * 销毁实例
   */
  destroy() {
    this.cleanup();
    this.callbacks = {};
  }
}

/**
 * 音频工具函数
 */
export const AudioUtils = {
  /**
   * 将音频 Blob 转换为 Base64
   */
  blobToBase64(blob) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result);
      reader.onerror = reject;
      reader.readAsDataURL(blob);
    });
  },
  
  /**
   * 下载音频文件
   */
  downloadAudio(blob, filename = `recording_${Date.now()}.webm`) {
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  },
  
  /**
   * 获取音频时长
   */
  getAudioDuration(blob) {
    return new Promise((resolve, reject) => {
      const audio = new Audio();
      const url = URL.createObjectURL(blob);
      
      audio.onloadedmetadata = () => {
        resolve(audio.duration);
        URL.revokeObjectURL(url);
      };
      
      audio.onerror = () => {
        reject(new Error('无法加载音频文件'));
        URL.revokeObjectURL(url);
      };
      
      audio.src = url;
    });
  },
  
  /**
   * 格式化时长显示
   */
  formatDuration(seconds) {
    if (!seconds || isNaN(seconds)) return '00:00';
    
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const secs = Math.floor(seconds % 60);
    
    if (hours > 0) {
      return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
    } else {
      return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
    }
  }
};